classdef ProjectNamingManager < handle
    %ProjectNamingManager 项目命名管理类
    %   管理项目命名约定配置，从CSV读取key-value对应关系
    %   实现单例模式，提供统一的命名规则查询接口
    %
    %   示例:
    %   ProjectNamingManager.getNameStr('model data', 'MyModel')
    %   ProjectNamingManager.listAvailableKeys()
    
    properties (Access = private)
        nameMap = [];       % 键值映射 containers.Map
        rootDir = '';       % 项目根目录
    end
    
    methods (Access = private)
        function obj = ProjectNamingManager()
            % 私有构造函数，实现单例模式
            obj.initializeConfig();
        end
        
        function initializeConfig(obj)
            % 初始化配置
            try
                % 基于当前文件位置计算项目根目录
                currentFile = mfilename('fullpath');
                configDir = fileparts(currentFile);
                obj.rootDir = fileparts(configDir);
                
                obj.loadConfig();
            catch ME
                warning('ProjectNamingManager:InitializationFailed', ...
                      '配置初始化失败，将使用空配置: %s', ME.message);
                obj.nameMap = containers.Map();
            end
        end
        
        function loadConfig(obj)
            % 加载CSV配置文件
            configPath = fullfile(obj.rootDir, 'project_configuration', 'naming_convention_simple.csv');
            
            if ~exist(configPath, 'file')
                warning('ProjectNamingManager:ConfigNotFound', ...
                       '配置文件未找到: %s', configPath);
                obj.nameMap = containers.Map();
                return;
            end
            
            try
                % 读取CSV文件
                data = readtable(configPath, 'Delimiter', ',', 'Encoding', 'UTF-8');
                
                % 验证格式
                if ~all(ismember({'Key', 'Pattern'}, data.Properties.VariableNames))
                    error('CSV文件格式无效，需要包含 Key 和 Pattern 列');
                end
                
                % 创建映射
                obj.nameMap = containers.Map();
                for i = 1:height(data)
                    key = char(data.Key(i));
                    pattern = char(data.Pattern(i));
                    obj.nameMap(key) = pattern;
                end
                
                fprintf('加载了 %d 个命名配置项\n', obj.nameMap.Count);
                
            catch ME
                error('ProjectNamingManager:LoadError', ...
                      '配置文件加载失败: %s', ME.message);
            end
        end
    end
    
    methods (Static)
        function obj = getInstance()
            % 获取单例实例
            persistent instance;
            if isempty(instance) || ~isvalid(instance)
                instance = ProjectNamingManager();
            end
            obj = instance;
        end
        
        function nameStr = getNameStr(key, modelName)
            % 获取名称字符串
            % 输入: key - 配置键值, modelName - 模型名称（可选）
            % 输出: nameStr - 名称字符串
            
            obj = ProjectNamingManager.getInstance();
            
            if ~obj.nameMap.isKey(key)
                error('ProjectNamingManager:KeyNotFound', ...
                      '未找到配置键: %s', key);
            end
            
            pattern = obj.nameMap(key);
            
            % 如果模式包含<MODEL>占位符，需要替换
            if contains(pattern, '<MODEL>')
                if nargin < 2 || isempty(modelName)
                    error('ProjectNamingManager:ModelNameRequired', ...
                          '配置项 "%s" 需要模型名称', key);
                end
                nameStr = strrep(pattern, '<MODEL>', modelName);
            else
                nameStr = pattern;
            end
        end
        
        function keyList = listAvailableKeys()
            % 列出所有可用的配置键
            obj = ProjectNamingManager.getInstance();
            keyList = keys(obj.nameMap);
        end
        
        function reloadConfig()
            % 重新加载配置
            obj = ProjectNamingManager.getInstance();
            obj.loadConfig();
            fprintf('配置已重新加载\n');
        end
    end
end

